package math

import "cmp"

//阶乘
func Factorial(a uint64) uint64 {
	var r uint64 = 1
	for i := a; i > 1; i-- {
		r *= i
	}
	return r
}

//排列
func Permutation(a, s uint64) uint64 {
	if s == 0 || s > a {
		return 1
	}
	var r uint64 = 1
	for i := a; i > a-s; i-- {
		r *= i
	}
	return r
}

//组合
func Combination(a, s uint64) uint64 {
	return Permutation(a, s) / Factorial(s)
}

//最大公因数:两个数能够整除该数
func GCD(m, n uint64) uint64 {
	if m < n {
		m, n = n, m
	}
	for n != 0 {
		m, n = n, m%n
	}
	return m
}

//最小公倍数：两个数能被该数整除
func LCM(m, n uint64) uint64 {
	return m * n / GCD(m, n)
}

//绝对值
func AbsInt64(x int64) uint64 {
	if x < 0 {
		return uint64(-x)
	}
	return uint64(x)
}

func Max[T cmp.Ordered](a T, v ...T) T {
	r := a
	for _, b := range v {
		if a < b {
			r = b
		}
	}
	return r
}

func Min[T cmp.Ordered](a T, v ...T) T {
	r := a
	for _, b := range v {
		if b < a {
			r = b
		}
	}
	return r
}
